package obs;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class OneThread {
    public static void main(String[] args) {
        MeiMei meiMei = new MeiMei();
        XiaoMing xiaoMing = new XiaoMing();
        XiaoZhang xiaoZhang = new XiaoZhang();
        XiaoZhangMum xiaoZhangMum = new XiaoZhangMum();
        xiaoZhang.addMum(xiaoZhangMum);
        meiMei.addObs(xiaoMing);
        meiMei.addObs(xiaoZhang);
        meiMei.setAge(10);
        System.out.println(xiaoMing.getAge());
        System.out.println(xiaoZhang.getAge());
        System.out.println(xiaoZhangMum.getAge());
        meiMei.setAge(14);
        System.out.println(xiaoMing.getAge());
        System.out.println(xiaoZhang.getAge());
        System.out.println(xiaoZhangMum.getAge());
        meiMei.setAge(18);
        System.out.println(xiaoMing.getAge());
        System.out.println(xiaoZhang.getAge());
        System.out.println(xiaoZhangMum.getAge());


        meiMei.addObs(new Obs() {
            @Override
            public void update(MeiMei meiMei) {
                System.out.println("一个匿名哥哥比妹妹大七岁　哥哥年龄"+(meiMei.getAge()+7));
            }
        });
        meiMei.addObs(new Obs() {
            @Override
            public void update(MeiMei meiMei) {
                System.out.println("一个匿名哥哥比妹妹大九岁　哥哥年龄"+(meiMei.getAge()+9));
            }
        });
        meiMei.setAge(40);
        System.out.println(xiaoMing.getAge());
        System.out.println(xiaoZhang.getAge());
        System.out.println(xiaoZhangMum.getAge());
    }

}
class MeiMei implements Cloneable{

    private int age;
//    其他属性省略

    private List<Obs> obs = new ArrayList<>();
    public void addObs(Obs o){
        this.obs.add(o);
    }
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
        for (Obs ob : this.obs) {
            try {
                Object clone = this.clone();
                ob.update((MeiMei) clone);
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }

        }

    }
}
interface  Obs {
    void update(MeiMei meiMei);
}
class XiaoMing implements Obs {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void update(final MeiMei meiMei) {

        this.setAge(meiMei.getAge()+6);
//        try {
//            Field age = meiMei.getClass().getDeclaredField("age");
//            age.setAccessible(true);
//            age.setInt(meiMei,7);
//        } catch (NoSuchFieldException | IllegalAccessException e) {
//            e.printStackTrace();
//        }
    }
}
class XiaoZhang implements Obs{
    private int age;

    private List<Obs2> mums = new ArrayList<>();
    public void addMum(Obs2 o){
        this.mums.add(o);
    }
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
        for (Obs2 mum : mums) {
            mum.update(this);
        }
    }

    @Override
    public void update(final MeiMei meiMei) {
        this.setAge(meiMei.getAge()+8);
    }
}
interface  Obs2 {
    void update(XiaoZhang xiaoZhang);
}
class XiaoZhangMum implements Obs2{
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void update( final XiaoZhang xiaoZhang) {
        this.setAge(xiaoZhang.getAge()+30);
    }
}
//观察者模式中，之所以叫观察者，就是只看不改变，只读不写，
//回调函数一定发生在事件之后　回调函数的传入参数是事件，只读不写。